package cn.net.dpi.util;

import java.util.zip.CRC32;

/**
 * Copyright(c) 2021 Dayou Positioning Intelligence Co.,Ltd
 * All rights reserved.
 *
 * @Date 2022/3/7
 * @Author changguoshan (changguoshan@dayoupi.cn)
 * @Version 0.2
 * @Reviewer
 */
public class CheckCodeUtil {

    /*校验码前10位字符串截取起始位*/
    private static final int FIRST_INDEX = 0;
    /*校验码后10位字符串截取截至位*/
    private static final int LAST_INDEX = 10;
    /*取余用的底数*/
    private static final int REMAINDER = 10;
    /*字符串填充*/
    private static final String FILLING_STR = "0";
    /*32位校验码长度*/
    private static final int CHECK_CODE_LENGTH = 32;
    /*字节数组的长度所占用的位数*/
    private static final int BYTES_LENGTH_REMAINDER = 1;

    /**
     * 根据byte数组生成32位校验码，用于验证数据前后是否产生变化
     *
     * @param bytes 字节数组
     * @return 32位校验码
     */
    public static String generate(byte[] bytes) {
        StringBuffer remainderString = new StringBuffer();
        //将字节数根据10取余，将余数进行拼接成余数字符串
        for (int i = 0; i < bytes.length; i++) {
            remainderString.append(bytes[i] % REMAINDER);
        }
        //根据字节数组长度和10进行取余，将此数作为32位校验码的最后一位
        int lengthRemainder = bytes.length % REMAINDER;
        //如果余数字符串加上字节数组的长度所占用的位数小于等于32，如果不足32位则补充0
        if (remainderString.length() + BYTES_LENGTH_REMAINDER <= CHECK_CODE_LENGTH) {
            //补充0的字符串
            StringBuilder fillingZeroString = new StringBuilder();
            //补充字符串的个数
            int fillingZeroNum = CHECK_CODE_LENGTH - (remainderString.length() + BYTES_LENGTH_REMAINDER);
            for (int i = 0; i < fillingZeroNum; i++) {
                fillingZeroString.append(FILLING_STR);
            }
            return remainderString.append(fillingZeroString).append(lengthRemainder).toString();
        } else {
            //中间10位检验码起始索引
            int middleStart = remainderString.length() / 2 - 5;
            //前10位校验码
            String startNum = remainderString.substring(FIRST_INDEX, LAST_INDEX);
            //后10位校验码
            String endNum = remainderString.substring(remainderString.length() - LAST_INDEX);
            //中间10位校验码
            String middleNum = remainderString.substring(middleStart, middleStart + LAST_INDEX);
            StringBuilder numString = new StringBuilder();
            return numString.append(startNum).append(middleNum).append(endNum).append(FILLING_STR).append(lengthRemainder).toString();
        }
    }

    /**
     * 使用CRC32生成9位校验码
     *
     * @param bytes
     * @return 校验码
     */
    public static Long crc32Generate(byte[] bytes){
        CRC32 crc32 = new CRC32();
        crc32.update(bytes);
        return crc32.getValue();
    }
}
